//
//  WLSocketManager.m
//  WanLian
//
//  Created by muzhuang on 2018/11/2.
//  Copyright © 2018年 wanlian. All rights reserved.
//

#import "WLSocketManager.h"
#import "WLSocketFileModel.h"
#import "GCDMulticastDelegate.h"

NSString* const HOST_ROUTER = @"192.168.188.1";
//NSString* const HOST_REMOTE = @"47.75.195.106";
NSString* const HOST_REMOTE = @"61.153.186.12";

//自动重连次数
//NSInteger autoConnectCount = 6;

@interface WLSocketManager ()<GCDAsyncSocketDelegate>
//{
//    GCDMulticastDelegate <RouterSocketDelegate>*_module;
//}

@property (strong , nonatomic) GCDMulticastDelegate <RouterSocketDelegate>*socketDelegate;
////初始化
//@property (strong , nonatomic) GCDAsyncSocket *routerSocket;
//自动重连次数
@property (nonatomic, assign) NSInteger autoConnectCount;
//是否主动断开
@property (nonatomic, assign) BOOL isDisconnectByUser;
//所有的代理
@property (nonatomic, strong) NSMutableArray *delegates;
//心跳定时器
@property (nonatomic, strong) dispatch_source_t beatTimer;
//发送心跳次数
@property (nonatomic, assign) NSInteger senBeatCount;
//路由器连接次数
@property (nonatomic, assign) NSInteger routerRegCount;

@property (nonatomic, strong) NSMutableArray *receiveData;//NSMutableData

@end

@implementation WLSocketManager

#pragma mark - 网络监听
- (void)networkChanged:(NSNotification *)notification {
    
    //    if (_connectStatus == SocketConnectStatus_DisconnectByUser) return; //主动断开连接
    
    //网络中断 , 断开连接
//    if (networkStatus == RealStatusNotReachable||_isConnected == NO) {
//        [self disconnect];//断开连接,默认还会重连3次 ,还未连接自动断开
//    }
    
    //如果网络监测有网 , 但是socket处于未连接状态 , 进行重连
//    if (networkStatus == RealStatusViaWWAN || networkStatus == RealStatusViaWiFi) {
//
//        if (_isConnected == NO) {
//
//            [self connectServerHost]; //连接服务器
//        }
//    }
}

- (dispatch_source_t)beatTimer
{
    if (!_beatTimer) {
        WLWkSelf
        _beatTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
        dispatch_source_set_timer(_beatTimer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);//心跳频率为1
        dispatch_source_set_event_handler(_beatTimer, ^{
            
            //发送心跳 +1
            weakSelf.senBeatCount ++ ;
            //超过3次未收到服务器心跳 , 置为未连接状态
            if (weakSelf.senBeatCount>15)//丢包5次
            {
                //更新连接状态
                weakSelf.isRegistered = NO;
                weakSelf.socketState = WLConnectionStateDisconnected;
                [weakSelf lostConnectAndReconnect];
            }
            else
            {
                //发送心跳
                NSDictionary *dict = @{@"type":@"PING",@"content":@""};
//                NSError *error;
//                NSData *jsonDataMsg = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
//                if (error) {
//                    return;
//                }
                [weakSelf sendOtherMessage:dict timeOut:-1 tag:0];
//                [weakSelf sendMessage:dict timeOut:-1 tag:0];
//                NSLog(@"------------------发送了心跳------------------");
            }
        });
    }
    return _beatTimer;
}

#pragma mark - 发送心跳
- (void)sendBeat
{
    if (_beatTimer) {
        dispatch_source_cancel(_beatTimer);
        _beatTimer = nil;
        _senBeatCount = 0;
    }
    //已经连接
//    _isRegistered = YES;
    //定时发送心跳开启
    dispatch_resume(self.beatTimer);
}

- (NSMutableArray *)receiveData
{
    if ((!_receiveData)) {
        _receiveData = [[NSMutableArray alloc] init];
    }
    return _receiveData;
}

- (void)clearAllDatas
{
    [self.receiveData removeAllObjects];
}

+ (WLSocketManager *)sharedSocketManager
{
    static WLSocketManager *socket = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        socket = [[WLSocketManager alloc] init];
    });
    return socket;
}

- (instancetype)init
{
    if (self = [super init]) {
        
        _autoConnectCount = 4;
        //将handler设置成接收TCP信息的代理
        _routerSocket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
        //设置默认关闭读取
        //        [_routerSocket setAutoDisconnectOnClosedReadStream:NO];
//        //默认状态未连接
//        _connectStatus = SocketConnectStatus_UnConnected;
        _socketState = WLConnectionStateDisconnected;
    }
    return self;
}

#pragma mark - 连接服务器端口
- (void)connectServerHost
{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSDate *lastDate = [userDefaults objectForKey:@"restartTime"];
    if (lastDate != nil) {
        NSTimeInterval timeInterval = [[NSDate date] timeIntervalSinceDate:lastDate];
        if (timeInterval<30)
        {
            return;
        }
        else
        {
            [userDefaults removeObjectForKey:@"restartTime"];
        }
    }
    NSError *error = nil;
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    if (manager.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWWAN)//如果是蜂窝网
    {
        _socketState = WLConnectionStateConnecting;
        BOOL connectStatus = [_routerSocket connectToHost:HOST_REMOTE onPort:9001 error:&error];
        if (!connectStatus) {
            _socketState = WLConnectionStateDisconnected;
            [[NSNotificationCenter defaultCenter] postNotificationName:@"RouterDisonnected" object:nil];
        }
        WLLog(@"----------------如果是蜂窝网络，直接连接服务器----------------,%@,%@,%@",error.description,_routerSocket.localHost,_routerSocket.connectedHost);
        return;
    } else if (manager.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWiFi) {
        _socketState = WLConnectionStateConnecting;
        BOOL connectedWifi = [WLCommonTool isConnectedTianYiLian];
        if (connectedWifi==NO)
        {
            BOOL isSucRemote =[_routerSocket connectToHost:HOST_REMOTE onPort:9001 error:&error];
            if (!isSucRemote) {
                _socketState = WLConnectionStateDisconnected;
                [[NSNotificationCenter defaultCenter] postNotificationName:@"RouterDisonnected" object:nil];
            }
            WLLog(@"----------------不是tianyilian的Wi-Fi，直接连接服务器----------------,%@,%@,%@",error.description,_routerSocket.localHost,_routerSocket.connectedHost);
            return;
        }
        BOOL isSucc = [_routerSocket connectToHost:HOST_ROUTER onPort:9001 error:&error];
        if (!isSucc)
        {
            BOOL isConnected = [_routerSocket connectToHost:HOST_REMOTE onPort:9001 error:&error];
            if (!isConnected) {
                _socketState = WLConnectionStateDisconnected;
                [[NSNotificationCenter defaultCenter] postNotificationName:@"RouterDisonnected" object:nil];
            }
            WLLog(@"----------------路由连接失败，连接远程服务器----------------,%@,%ld",error.description,(long)_autoConnectCount);
        }
    }
    WLLog(@"----------------连接服务器情况----------------,%@,%@,%@",error.description,_routerSocket.localHost,_routerSocket.connectedHost);
}




- (void)connectRemoteServerHost
{
    _socketState = WLConnectionStateConnecting;
    NSError *error = nil;
    BOOL isConnected = [_routerSocket connectToHost:HOST_REMOTE onPort:9001 error:&error];
    if (!isConnected) {
        _socketState = WLConnectionStateDisconnected;
        [[NSNotificationCenter defaultCenter] postNotificationName:@"RouterDisonnected" object:nil];
    }
}

- (void)routerSocketRegister
{
    NSDictionary *dictContent = @{@"publickey":[[WLUseManager shareUser] getUserRouterTag]};
    NSError *parseError;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictContent options:NSJSONWritingPrettyPrinted error:&parseError];
    
    NSString *strContent = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    NSDictionary *dict = @{@"type":@"REGISTER",@"bNew":@(YES),@"content":strContent};
    [self sendOtherMessage:dict timeOut:-1 tag:1001];
//    [self sendMessage:dict timeOut:-1 tag:1001];//dictMessage[@"bNew"] = @(true);
}

#pragma mark- GCDAsyncSocketDelegate
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    if ([[WLUseManager shareUser] isLogin]==NO) {
        [self userManualdisconnect];
        return;
    }
    
//    _socketState = WLConnectionStateDisconnected;
    
    if ([sock.connectedHost isEqualToString:HOST_ROUTER]) {
        _socketState = WLConnectionStateRouter;
    }
    else if ([sock.connectedHost isEqualToString:HOST_REMOTE])
    {
        _socketState = WLConnectionStateRemote;
    }
//    //开始发送心跳
    [self sendBeat];
    //重新建立连接后 , 重置自动重连次数
    _autoConnectCount = 4;
    
    _senBeatCount = 0;
//    _isConnected  = YES;;
    WLLog(@"连接成功");
    
    [self routerSocketRegister];
}

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
    [self lostConnectAndReconnect];
}
- (void)lostConnectAndReconnect {
    
    [[NSNotificationCenter defaultCenter] postNotificationName:KRouterWillDisonnected object:nil];
    WLLog(@"连接断开了");
    _isRegistered = NO;
    //处理用户手动断开的逻辑
    if (_isDisconnectByUser == YES) {
        _isDisconnectByUser = NO;
        [self configDidDisConnectState];
        return;
    }
    
    //自动重连
    if (_autoConnectCount > 0) {
        
        [self closeSendHeartBeat];
        
        if (![[WLUseManager shareUser] isLogin]) {
            return;
        }
        [self connectServerHost];
        WLLog(@"-------------第%ld次重连--------------",(long)_autoConnectCount);
        _autoConnectCount -- ;
    }else{
        WLLog(@"----------------重连次数已用完------------------");
        [self configDidDisConnectState];
    }
}
- (void)configDidDisConnectState {
    
    _socketState = WLConnectionStateDisconnected;
    _autoConnectCount = 4;
    //关闭心跳定时器
    [self closeSendHeartBeat];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"RouterDisonnected" object:nil];
}
- (void)closeSendHeartBeat {
    
    if (_beatTimer) {
        dispatch_source_cancel(_beatTimer);
        _beatTimer = nil;
        //未接收到服务器心跳次数,置为初始化
        _senBeatCount = 0;
    }
}
- (void)userManualdisconnect
{
    
    _socketState = WLConnectionStateDisconnected;
    _isDisconnectByUser = YES;
    //重连次数 , 置为0
    _autoConnectCount = 4;
    //断开连接
    [_routerSocket disconnect];
    //关闭心跳定时器
    [self closeSendHeartBeat];
    _isRegistered = NO;
}

- (void)disconnect
{
    _socketState = WLConnectionStateDisconnected;
    _isDisconnectByUser = NO;
    //自动重连次数 , 置为初始化
    _autoConnectCount = 4;
//    //重连次数 , 置为0
//    _autoConnectCount = 0;
//    WLLog(@"duankai");
    //断开连接
    [_routerSocket disconnect];
    //关闭心跳定时器
    [self closeSendHeartBeat];
    _isRegistered = NO;
}

- (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag
                 elapsed:(NSTimeInterval)elapsed
               bytesDone:(NSUInteger)length
{
    WLLog(@"发送消息超时：%f,%lu",elapsed,(unsigned long)length);
    //发送超时消息分发
    for (id<RouterSocketDelegate> delegate in self.delegates) {
        if ([delegate respondsToSelector:@selector(sendMessageTimeOutWithTag:)]) {
            [delegate sendMessageTimeOutWithTag:tag];
        }
    }
    return -1;
}

- (GCDMulticastDelegate <RouterSocketDelegate> *)socketDelegate
{
    if (!_socketDelegate) {
        _socketDelegate = (GCDMulticastDelegate <RouterSocketDelegate> *)[[GCDMulticastDelegate alloc] init];
    }
    return _socketDelegate;
}

- (NSMutableArray *)delegates
{
    //    GCDMulticastDelegate <MyPluginDelegate> *multicastDelegate;
    //    multicastDelegate = (GCDMulticastDelegate <MyPluginDelegate> *)[[GCDMulticastDelegate alloc] init];
    if (!_delegates) {
        _delegates = [NSMutableArray array];
    }
    return _delegates;
}

#pragma mark - 添加代理
- (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue
{
    if (delegateQueue==nil) {
        [self.socketDelegate addDelegate:delegate delegateQueue:dispatch_get_main_queue()];
    }
    else
    {
        [self.socketDelegate addDelegate:delegate delegateQueue:delegateQueue];
    }
}

#pragma mark - 移除代理
- (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue
{
    if (delegateQueue==nil) {
        [self.socketDelegate removeDelegate:delegate delegateQueue:dispatch_get_main_queue()];
    }
    else
    {
        [self.socketDelegate removeDelegate:delegate delegateQueue:delegateQueue];
    }
}

#pragma mark - 添加代理
- (void)addDelegate:(id<RouterSocketDelegate>)delegate// delegateQueue:(dispatch_queue_t)queue
{
//    if (![self.delegates containsObject:delegate]) {
//        [self.delegates addObject:delegate];
//    }
}

#pragma mark - 移除代理
- (void)removeDelegate:(id<RouterSocketDelegate>)delegate
{
//    [self.delegates removeObject:delegate];
}

- (NSData *)dataFromInt:(int)num {
    unsigned char * arr = (unsigned char *) malloc(sizeof(num) * sizeof(unsigned char));
    for (int i = sizeof(num) - 1 ; i >= 0; i --) {
        arr[i] = num & 0xFF;
        num = num >> 8;
    }
    NSData * data = [NSData dataWithBytes:arr length:sizeof(num)];
    free(arr);
    return data;
}

- (int) intFromData:(NSData *)data
{
    int intSize = sizeof(int); // change it to fixe length
    unsigned char * buffer = malloc(intSize * sizeof(unsigned char));
    [data getBytes:buffer length:intSize];
    int num = 0;
    for (int i = 0; i < intSize; i++) {
        num = (num << 8) + buffer[i];
    }
    free(buffer);
    return num;
}

#pragma mark - 发送注册心跳消息
- (void)sendOtherMessage:(NSDictionary *)dictMsg timeOut:(NSUInteger)timeOut tag:(long)tag
{
    NSMutableDictionary *dictMessage = [[NSMutableDictionary alloc] initWithDictionary:dictMsg];
    dictMessage[@"clientId"] = [[WLUseManager shareUser] getUserRouterTag];
    if (_socketState==WLConnectionStateRouter)//([_routerSocket.connectedHost isEqualToString:HOST_ROUTER])
    {
        dictMessage[@"tagClientId"] = [[WLUseManager shareUser] getUserCurrentRouter];
    }
    else
    {
        dictMessage[@"tagClientId"] = @"d5c0bfaca2934f22bc3f8ff4b7b0dc97";
    }
    NSError *error;
    NSData *jsonDataMsg = [NSJSONSerialization dataWithJSONObject:dictMessage options:NSJSONWritingPrettyPrinted error:&error];
    if (error) {
        return;
    }
    
    NSData *data76 = [self dataFromInt:118];
    NSData *data01 = [self dataFromInt:1];
    NSData *data1 = [self dataFromInt:1];
    NSData *dataLength = [self dataFromInt:(int)jsonDataMsg.length];
    NSMutableData *body = [[NSMutableData alloc] init];
    [body appendData:data76];
    [body appendData:data01];
    [body appendData:data1];
    [body appendData:dataLength];
    [body appendData:jsonDataMsg];
    //写入数据
    [_routerSocket writeData:body withTimeout:timeOut tag:tag];
//    if (tag != 101)
//    {
//    WLLog(@"写入参数：%@",dictMsg);
//    }
}

#pragma mark - 发送消息
- (void)sendMessage:(NSDictionary *)dictMsg timeOut:(NSUInteger)timeOut tag:(long)tag
{
    NSMutableDictionary *dictMessage = [[NSMutableDictionary alloc] initWithDictionary:dictMsg];
    dictMessage[@"clientId"] = [[WLUseManager shareUser] getUserRouterTag];
    dictMessage[@"tagClientId"] = [[WLUseManager shareUser] getUserCurrentRouter];
//    dictMessage[@"bNew"] = @(YES);
    NSError *error;
    NSData *jsonDataMsg = [NSJSONSerialization dataWithJSONObject:dictMessage options:NSJSONWritingPrettyPrinted error:&error];
    if (error) {
        return;
    }
//    NSString *messageJson = msgModel.mj_JSONString;
//    //以"\n"分割此条消息 , 支持的分割方式有很多种例如\r\n、\r、\n、空字符串,不支持自定义分隔符,具体的需要和服务器协商分包方式 , 这里以\n分包
//    /*
//     如不进行分包,那么服务器如果在短时间里收到多条消息 , 那么就会出现粘包的现象 , 无法识别哪些数据为单独的一条消息 .
//     对于普通文本消息来讲 , 这里的处理已经基本上足够 . 但是如果是图片进行了分割发送,就会形成多个包 , 那么这里的做法就显得并不健全,严谨来讲,应该设置包头,把该条消息的外信息放置于包头中,例如图片信息,该包长度等,服务器收到后,进行相应的分包,拼接处理.
//     */
//    messageJson           = [messageJson stringByAppendingString:@"\n"];
//    //base64编码成data
//    NSData  *jsonDataMsg  = [[NSData alloc]initWithBase64EncodedString:messageJson options:NSDataBase64DecodingIgnoreUnknownCharacters];
//    int headInt = 118;
//    NSMutableData *bodyHead = [[NSMutableData alloc] init];
//    [bodyHead appendBytes:&headInt length:sizeof(headInt)];
//    WLLog(@"bodyHead:%@",bodyHead);
    
    NSData *data76 = [self dataFromInt:118];
    NSData *data01 = [self dataFromInt:1];
    NSData *data1 = [self dataFromInt:1];
    NSData *dataLength = [self dataFromInt:(int)jsonDataMsg.length];
    NSMutableData *body = [[NSMutableData alloc] init];
    [body appendData:data76];
    [body appendData:data01];
    [body appendData:data1];
    [body appendData:dataLength];
    [body appendData:jsonDataMsg];
    //写入数据
    [_routerSocket writeData:body withTimeout:timeOut tag:tag];
//    if (tag != 101)
//    {
        WLLog(@"写入参数：%@",dictMessage);
//    }
}

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    WLLog(@"写成功:%ld",tag);
    [self.routerSocket readDataWithTimeout:-1 tag:tag];
}

- (void)socket:(GCDAsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag
{
//    self.currentSendItem.upSize += partialLength;
//    if ([self.delegate respondsToSelector:@selector(socketManager:itemUpingrefresh:)] && (tag<self.needSendItems.count)) {
//        SockerSendItem *item = self.needSendItems[tag];
//        item.isSending = YES;
//        [self.delegate socketManager:self itemUpingrefresh:item];
//    }
//    WLLog(@"%f--tag = %zd",((self.currentSendItem.upSize * 1.0) / self.currentSendItem.fileSize),tag);
}

#pragma mark - 接收到消息
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    int value = 0;
    int length = 0;
    if (data.length >= 16) {
        NSData *data4 = [data subdataWithRange:NSMakeRange(0, 4)];
        value = CFSwapInt32BigToHost(*(int*)([data4 bytes]));
        //    int testHead;
        //    [data getBytes:&testHead range:NSMakeRange(0, 4)];
        //    WLLog(@"headlength:%d",testHead);
        
        //    NSData *dataV = [data subdataWithRange:NSMakeRange(4, 4)];
        //    int version = CFSwapInt32BigToHost(*(int*)([dataV bytes]));
        //    NSData *dataVE = [data subdataWithRange:NSMakeRange(8, 4)];
        //    int type = CFSwapInt32BigToHost(*(int*)([dataVE bytes]));
        NSData *dataL = [data subdataWithRange:NSMakeRange(12, 4)];
        length = CFSwapInt32BigToHost(*(int*)([dataL bytes]));
    }
    
//    unsigned int le;
//    [data getBytes:&le range:NSMakeRange(12, 4)];
    if (value==118&&length<=data.length-16) {
        [self socket:sock parsePackage:[data subdataWithRange:NSMakeRange(16, length)] withTag:tag];
    }
    else
    {
        WLLog(@"!!!!!粘包数据,%lu",(unsigned long)self.receiveData.count);
        if (self.receiveData.count>4)//先丢包处理，可找到里面的包头再处理
        {
            [self.receiveData removeAllObjects];
            [self.routerSocket readDataWithTimeout:-1 tag:tag];
            return;
        }
        if (self.receiveData.count>0)
        {
            [self.receiveData addObject:data];
            NSData *dataTotal = [[self.receiveData objectAtIndex:0] subdataWithRange:NSMakeRange(12, 4)];
            int totalLength = CFSwapInt32BigToHost(*(int*)([dataTotal bytes]));
            WLLog(@"!!!!!缓存：%d,%@",totalLength,self.receiveData);
            int curlen = 0;
            for (int i=0; i<self.receiveData.count; i++) {
                curlen += [[self.receiveData objectAtIndex:i] length];
            }
            if (curlen>=totalLength) {
                NSMutableData *completeData = [[NSMutableData alloc] init];
                for (int j=0; j<self.receiveData.count; j++) {
                    [completeData appendData:[self.receiveData objectAtIndex:j]];
                }
                [self socket:sock parsePackage:[completeData subdataWithRange:NSMakeRange(16, totalLength)] withTag:tag];
                NSData *dataLeft = [completeData subdataWithRange:NSMakeRange(totalLength+16, completeData.length-totalLength-16)];
                [self.receiveData removeAllObjects];
                if (dataLeft.length>4)
                {
                    WLLog(@"!!!!!left data:%@",dataLeft);
                    NSData *dataHead = [dataLeft subdataWithRange:NSMakeRange(0, 4)];
                    int valueHead = CFSwapInt32BigToHost(*(int*)([dataHead bytes]));
                    if (valueHead==118)
                    {
                        [self.receiveData addObject:dataLeft];
                    }
                    else
                    {
                        WLLog(@"!!!!!111111:%@",dataLeft);
//                        [self.receiveData removeAllObjects];
                    }
                }
                else
                {
                    WLLog(@"!!!!!222222:%@",dataLeft);
//                    [self.receiveData removeAllObjects];
                }
            }
            else
            {
                WLLog(@"!!!!!33333:%@",self.receiveData);
            }
        }
        else
        {
            if (value !=118) {
                WLLog(@"!!!!!unknow data:%@",data);
                NSData *data76 = [self dataFromInt:118];
                NSRange range = [data rangeOfData:data76 options:NSDataSearchBackwards range:NSMakeRange(0, data.length)];
//                Byte *testByte = (Byte *)[data bytes];
//                for(int i=0;i<[data length];i++)
//                {
//                    printf("testByte = %d\n",testByte[i]);
//                }
                if (range.location != NSNotFound) {
                    NSData *dataSub = [data subdataWithRange:NSMakeRange(range.location, data.length-range.location)];
                    WLLog(@"!!!!!new data:%@",dataSub);
                    [self.receiveData addObject:dataSub];
                }
                else
                {
                    WLLog(@"!!!!!abandon:%@",data);
                }
            }
            else
            {
                [self.receiveData addObject:data];
            }
        }
//        [self.routerSocket readDataWithTimeout:-1 tag:0];
//        return;
    }
    [self.routerSocket readDataWithTimeout:-1 tag:tag];
    /*
    if (value !=116&&length>data.length-16)
    {
        if (self.receiveData.count>0)
        {
            [self.receiveData addObject:data];
            NSData *dataTotal = [[self.receiveData objectAtIndex:0] subdataWithRange:NSMakeRange(12, 4)];
            int totalLength = CFSwapInt32BigToHost(*(int*)([dataTotal bytes]));
            WLLog(@"缓存：%d,%@",totalLength,self.receiveData);
            int curlen = 0;
            for (int i=0; i<self.receiveData.count; i++) {
                curlen += [[self.receiveData objectAtIndex:i] length];
            }
            if (curlen>=totalLength) {
                NSMutableData *completeData = [[NSMutableData alloc] init];
                for (int j=0; j<self.receiveData.count; j++) {
                    [completeData appendData:[self.receiveData objectAtIndex:j]];
                }
                [self parsePackage:[completeData subdataWithRange:NSMakeRange(16, totalLength)]];
                [self.receiveData removeAllObjects];
            }
        }
        else
        {
            if (value !=116) {
                WLLog(@"unknow data:%@",data);
            }
            else
            {
                [self.receiveData addObject:data];
            }
        }
        [self.routerSocket readDataWithTimeout:-1 tag:0];
        return;
    }
    
    [self parsePackage:[data subdataWithRange:NSMakeRange(16, length)]];
    */
    /*
    NSDictionary *dictionary =[NSJSONSerialization JSONObjectWithData:[data subdataWithRange:NSMakeRange(16, length)] options:NSJSONReadingMutableLeaves error:nil];
//    NSDictionary *dictionary2 =[NSJSONSerialization JSONObjectWithData:[data subdataWithRange:NSMakeRange(16, length)] options:NSJSONReadingMutableLeaves error:nil];
//    NSString *secretStr  = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
//    //去除'\n'
//    secretStr = [secretStr stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    //转为消息模型(具体传输的json包裹内容,加密方式,包头设定什么的需要和后台协商,操作方式根据项目而定)
    WLSocketModel *messageModel = [WLSocketModel mj_objectWithKeyValues:dictionary];
//    WLLog(@"读成功%@,%d,%d,%d,%d,%@",receive,value,version,type,length,dictionary);
//    NSString *str = [self logDic:dictionary];
//    WLLog(@"读出参数：%@",messageModel.mj_keyValues.description);
    //接收到服务器的心跳
    if ([messageModel.type isEqualToString:@"PING_REPLY"]) {
        
        //接到服务器心跳次数置为0
        _senBeatCount = 0;
        WLLog(@"------------------接收到服务器心跳-------------------");
        return;
    }
    NSString * receive = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    WLLog(@"读成功%@,%d,%d,%d,%d,%@",receive,value,version,type,length,dictionary);
    if ([messageModel.type isEqualToString:@"REGISTER_SUCCESS"])
    {
        _isRegistered = YES;
        //开始发送心跳
        [self sendBeat];
        //重新建立连接后 , 重置自动重连次数
        autoConnectCount = 3;

        //发送普通消息失败回执
    }
    else if ([messageModel.type isEqualToString:@"COMMON_ERROR"]) {
//        if (tag==1001) {
//            [self routerSocketRegister];
//        }
//        dispatch_source_cancel(self.beatTimer);
//        self.beatTimer = nil;
//        if (tag==1001) {
//            _senBeatCount = 3;
//        }
    }
    else if ([messageModel.type isEqualToString:@"DEVICE_FILE_UPLOAD_REQ"])
    {
        
    }
    
    for (id delegate in self.delegates) {
        if ([delegate respondsToSelector:@selector(didReceiveMessage:)]) {
            [delegate didReceiveMessage:messageModel];
        }
    }
    */
}

- (void)socket:(GCDAsyncSocket *)socket parsePackage:(NSData *)data withTag:(long)tag
{
    NSString *strData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSString *strTrim =[strData stringByTrimmingCharactersInSet:[NSCharacterSet controlCharacterSet]];
    NSData *dataJson = [strTrim dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary =[NSJSONSerialization JSONObjectWithData:dataJson options:NSJSONReadingMutableLeaves|NSJSONReadingAllowFragments error:&error];
    WLSocketModel *messageModel = [WLSocketModel mj_objectWithKeyValues:dictionary];
    _senBeatCount = 0;
    if ([messageModel.type isEqualToString:@"PING_REPLY"]) {
        
        //接到服务器心跳次数置为0
        WLLog(@"------------------接收到服务器心跳-------------------");
        return;
    }
    WLLog(@"读成功:%@,%@",dictionary,socket.connectedHost);
    if ([messageModel.type isEqualToString:@"REGISTER_SUCCESS"])
    {
        if ([socket.connectedHost isEqualToString:HOST_ROUTER]) {
            _socketState = WLConnectionStateRouter;
        }
        else if ([socket.connectedHost isEqualToString:HOST_REMOTE])
        {
            _socketState = WLConnectionStateRemote;
        }
        
        _isRegistered = YES;
        //开始发送心跳
//        [self sendBeat];
        //重新建立连接后 , 重置自动重连次数
        _autoConnectCount = 4;
        
    }
    else if ([messageModel.type isEqualToString:WLSocketPacketTypeCOMMON_ERROR])
    {
        [self userManualdisconnect];
    }
    else if ([messageModel.type isEqualToString:WLSocketPacketTypePEER_MUST_OUT])
    {
        [self userManualdisconnect];
    } else if ([messageModel.type isEqualToString:WLSocketPacketTypeCOMMON_DEVICE_KEY_ERROR]) {
        [self userManualdisconnect];
    }
    
    [self.socketDelegate didReceiveMessage:messageModel withTag:(long)tag];
    
//    for (id delegate in self.delegates) {
//        if ([delegate respondsToSelector:@selector(didReceiveMessage:)]) {
//            [delegate didReceiveMessage:messageModel];
//        }
//    }
}

- (NSString *)logDic:(NSDictionary *)dic
{
    if (![dic count]) {
        return nil;
    }
    NSString *tempStr1 =
    [[dic description] stringByReplacingOccurrencesOfString:@"\\u"
                                                 withString:@"\\U"];
    NSString *tempStr2 =
    [tempStr1 stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
    NSString *tempStr3 =
    [[@"\"" stringByAppendingString:tempStr2] stringByAppendingString:@"\""];
    NSData *tempData = [tempStr3 dataUsingEncoding:NSUTF8StringEncoding];
    NSString *str = [NSPropertyListSerialization propertyListWithData:tempData options:NSPropertyListImmutable format:NULL error:NULL];
    //    [NSPropertyListSerialization propertyListFromData:tempData
    //                                     mutabilityOption:NSPropertyListImmutable
    //                                               format:NULL
    //                                     errorDescription:NULL];
    return str;
}

@end
